<!DOCTYPE html>



  


<html class="theme-next pisces use-motion" lang="zh-Hans">
<head>
  <meta charset="UTF-8"/>
<meta http-equiv="X-UA-Compatible" content="IE=edge" />
<meta name="viewport" content="width=device-width, initial-scale=1, maximum-scale=1"/>
<meta name="theme-color" content="#222">


<meta name="google-site-verification" content="E9deYnivN5MuHMuIfiMZZfS0alv-d_0UjcwjBL79lGU" />



<meta name="baidu-site-verification" content="iHYWJxscwD" />










<meta http-equiv="Cache-Control" content="no-transform" />
<meta http-equiv="Cache-Control" content="no-siteapp" />



  <meta name="google-site-verification" content="true" />








  <meta name="baidu-site-verification" content="true" />







  
  
  <link href="/lib/fancybox/source/jquery.fancybox.css?v=2.1.5" rel="stylesheet" type="text/css" />







<link href="/lib/font-awesome/css/font-awesome.min.css?v=4.6.2" rel="stylesheet" type="text/css" />

<link href="/css/main.css?v=5.1.4" rel="stylesheet" type="text/css" />


  <link rel="apple-touch-icon" sizes="180x180" href="/images/apple-touch-icon-next.png?v=5.1.4">


  <link rel="icon" type="image/png" sizes="32x32" href="/images/favicon-32x32-next.png?v=5.1.4">


  <link rel="icon" type="image/png" sizes="16x16" href="/images/favicon-16x16-next.png?v=5.1.4">


  <link rel="mask-icon" href="/images/logo.svg?v=5.1.4" color="#222">





  <meta name="keywords" content="学习笔记,量化投资,线性回归,Backtrader,多因子选股," />










<meta name="description" content="下面对上次实现的多因子选股模型进行一些改进。首先来看评分标准，增加几个系数。 123456789101112131415# 计算评分指标def scale(factors, a1&#x3D;1.0, a2 &#x3D; 1.0, a3 &#x3D; 1.0, a4 &#x3D; 1.0, a5 &#x3D; 1.0):    pe &#x3D; -1.0*a1*factors.pe&#x2F;factors.pe.mean()    esp &#x3D; a2*factors">
<meta property="og:type" content="article">
<meta property="og:title" content="量化投资学习笔记86——实现量化交易经典策略:多因子选股（改进1）">
<meta property="og:url" content="https://zwdnet.github.io/2020/08/29/%E9%87%8F%E5%8C%96%E6%8A%95%E8%B5%84%E5%AD%A6%E4%B9%A0%E7%AC%94%E8%AE%B086%E2%80%94%E2%80%94%E5%AE%9E%E7%8E%B0%E9%87%8F%E5%8C%96%E4%BA%A4%E6%98%93%E7%BB%8F%E5%85%B8%E7%AD%96%E7%95%A5-%E5%A4%9A%E5%9B%A0%E5%AD%90%E9%80%89%E8%82%A1%EF%BC%88%E6%94%B9%E8%BF%9B1%EF%BC%89/index.html">
<meta property="og:site_name" content="赵瑜敏的口腔医学专业学习博客">
<meta property="og:description" content="下面对上次实现的多因子选股模型进行一些改进。首先来看评分标准，增加几个系数。 123456789101112131415# 计算评分指标def scale(factors, a1&#x3D;1.0, a2 &#x3D; 1.0, a3 &#x3D; 1.0, a4 &#x3D; 1.0, a5 &#x3D; 1.0):    pe &#x3D; -1.0*a1*factors.pe&#x2F;factors.pe.mean()    esp &#x3D; a2*factors">
<meta property="og:locale">
<meta property="og:image" content="https://zymblog-1258069789.cos.ap-chengdu.myqcloud.com/blog0178-QTLearn/59/01.png">
<meta property="og:image" content="https://zymblog-1258069789.cos.ap-chengdu.myqcloud.com/blog0178-QTLearn/59/02.png">
<meta property="og:image" content="https://zymblog-1258069789.cos.ap-chengdu.myqcloud.com/blog0178-QTLearn/59/03.png">
<meta property="og:image" content="https://zymblog-1258069789.cos.ap-chengdu.myqcloud.com/blog0178-QTLearn/59/04.png">
<meta property="og:image" content="https://zymblog-1258069789.cos.ap-chengdu.myqcloud.com/blog0178-QTLearn/59/05.png">
<meta property="og:image" content="https://zymblog-1258069789.cos.ap-chengdu.myqcloud.com/blog0178-QTLearn/59/06.png">
<meta property="og:image" content="https://zymblog-1258069789.cos.ap-chengdu.myqcloud.com/blog0178-QTLearn/59/07.png">
<meta property="og:image" content="https://zymblog-1258069789.cos.ap-chengdu.myqcloud.com/blog0178-QTLearn/59/08.png">
<meta property="og:image" content="https://zymblog-1258069789.cos.ap-chengdu.myqcloud.com/blog0178-QTLearn/59/09.png">
<meta property="og:image" content="https://zymblog-1258069789.cos.ap-chengdu.myqcloud.com/blog0178-QTLearn/59/10.png">
<meta property="og:image" content="https://zymblog-1258069789.cos.ap-chengdu.myqcloud.com/blog0178-QTLearn/59/11.png">
<meta property="og:image" content="https://zymblog-1258069789.cos.ap-chengdu.myqcloud.com/blog0178-QTLearn/59/12.png">
<meta property="og:image" content="https://zymblog-1258069789.cos.ap-chengdu.myqcloud.com/blog0178-QTLearn/59/13.png">
<meta property="og:image" content="https://zymblog-1258069789.cos.ap-chengdu.myqcloud.com/blog0178-QTLearn/59/14.png">
<meta property="og:image" content="https://zymblog-1258069789.cos.ap-chengdu.myqcloud.com/blog0178-QTLearn/59/15.png">
<meta property="og:image" content="https://zymblog-1258069789.cos.ap-chengdu.myqcloud.com/other/wx.jpg">
<meta property="article:published_time" content="2020-08-29T01:07:36.000Z">
<meta property="article:modified_time" content="2020-08-30T05:52:04.000Z">
<meta property="article:author" content="赵瑜敏">
<meta property="article:tag" content="学习笔记">
<meta property="article:tag" content="量化投资">
<meta property="article:tag" content="线性回归">
<meta property="article:tag" content="Backtrader">
<meta property="article:tag" content="多因子选股">
<meta name="twitter:card" content="summary">
<meta name="twitter:image" content="https://zymblog-1258069789.cos.ap-chengdu.myqcloud.com/blog0178-QTLearn/59/01.png">



<script type="text/javascript" id="hexo.configurations">
  var NexT = window.NexT || {};
  var CONFIG = {
    root: '',
    scheme: 'Pisces',
    version: '5.1.4',
    sidebar: {"position":"left","display":"post","offset":12,"b2t":false,"scrollpercent":false,"onmobile":false},
    fancybox: true,
    tabs: true,
    motion: {"enable":true,"async":false,"transition":{"post_block":"fadeIn","post_header":"slideDownIn","post_body":"slideDownIn","coll_header":"slideLeftIn","sidebar":"slideUpIn"}},
    duoshuo: {
      userId: '0',
      author: '博主'
    },
    algolia: {
      applicationID: '',
      apiKey: '',
      indexName: '',
      hits: {"per_page":10},
      labels: {"input_placeholder":"Search for Posts","hits_empty":"We didn't find any results for the search: ${query}","hits_stats":"${hits} results found in ${time} ms"}
    }
  };
</script>



  <link rel="canonical" href="https://zwdnet.github.io/2020/08/29/量化投资学习笔记86——实现量化交易经典策略-多因子选股（改进1）/"/>





  <title>量化投资学习笔记86——实现量化交易经典策略:多因子选股（改进1） | 赵瑜敏的口腔医学专业学习博客</title>
  








<meta name="generator" content="Hexo 5.4.0"></head>

<body itemscope itemtype="http://schema.org/WebPage" lang="zh-Hans">

  
  
    
  

  <div class="container sidebar-position-left page-post-detail">
    <div class="headband"></div>

    <header id="header" class="header" itemscope itemtype="http://schema.org/WPHeader">
      <div class="header-inner"><div class="site-brand-wrapper">
  <div class="site-meta ">
    

    <div class="custom-logo-site-title">
      <a href="/"  class="brand" rel="start">
        <span class="logo-line-before"><i></i></span>
        <span class="site-title">赵瑜敏的口腔医学专业学习博客</span>
        <span class="logo-line-after"><i></i></span>
      </a>
    </div>
      
        <p class="site-subtitle"></p>
      
  </div>

  <div class="site-nav-toggle">
    <button>
      <span class="btn-bar"></span>
      <span class="btn-bar"></span>
      <span class="btn-bar"></span>
    </button>
  </div>
</div>

<nav class="site-nav">
  

  
    <ul id="menu" class="menu">
      
        
        <li class="menu-item menu-item-home">
          <a href="/%20" rel="section">
            
              <i class="menu-item-icon fa fa-fw fa-home"></i> <br />
            
            首页
          </a>
        </li>
      
        
        <li class="menu-item menu-item-tags">
          <a href="/tags/%20" rel="section">
            
              <i class="menu-item-icon fa fa-fw fa-tags"></i> <br />
            
            标签
          </a>
        </li>
      
        
        <li class="menu-item menu-item-categories">
          <a href="/categories/%20" rel="section">
            
              <i class="menu-item-icon fa fa-fw fa-th"></i> <br />
            
            分类
          </a>
        </li>
      
        
        <li class="menu-item menu-item-archives">
          <a href="/archives/%20" rel="section">
            
              <i class="menu-item-icon fa fa-fw fa-archive"></i> <br />
            
            归档
          </a>
        </li>
      

      
    </ul>
  

  
</nav>



 </div>
    </header>

    <main id="main" class="main">
      <div class="main-inner">
        <div class="content-wrap">
          <div id="content" class="content">
            

  <div id="posts" class="posts-expand">
    

  

  
  
  

  <article class="post post-type-normal" itemscope itemtype="http://schema.org/Article">
  
  
  
  <div class="post-block">
    <link itemprop="mainEntityOfPage" href="https://zwdnet.github.io/2020/08/29/%E9%87%8F%E5%8C%96%E6%8A%95%E8%B5%84%E5%AD%A6%E4%B9%A0%E7%AC%94%E8%AE%B086%E2%80%94%E2%80%94%E5%AE%9E%E7%8E%B0%E9%87%8F%E5%8C%96%E4%BA%A4%E6%98%93%E7%BB%8F%E5%85%B8%E7%AD%96%E7%95%A5-%E5%A4%9A%E5%9B%A0%E5%AD%90%E9%80%89%E8%82%A1%EF%BC%88%E6%94%B9%E8%BF%9B1%EF%BC%89/">

    <span hidden itemprop="author" itemscope itemtype="http://schema.org/Person">
      <meta itemprop="name" content="">
      <meta itemprop="description" content="">
      <meta itemprop="image" content="https://zymblog-1258069789.cos.ap-chengdu.myqcloud.com/other/tx.jpg">
    </span>

    <span hidden itemprop="publisher" itemscope itemtype="http://schema.org/Organization">
      <meta itemprop="name" content="赵瑜敏的口腔医学专业学习博客">
    </span>

    
      <header class="post-header">

        
        
          <h1 class="post-title" itemprop="name headline">量化投资学习笔记86——实现量化交易经典策略:多因子选股（改进1）</h1>
        

        <div class="post-meta">
          <span class="post-time">
            
              <span class="post-meta-item-icon">
                <i class="fa fa-calendar-o"></i>
              </span>
              
                <span class="post-meta-item-text">发表于</span>
              
              <time title="创建于" itemprop="dateCreated datePublished" datetime="2020-08-29T01:07:36+00:00">
                2020-08-29
              </time>
            

            

            
          </span>

          
            <span class="post-category" >
            
              <span class="post-meta-divider">|</span>
            
              <span class="post-meta-item-icon">
                <i class="fa fa-folder-o"></i>
              </span>
              
                <span class="post-meta-item-text">分类于</span>
              
              
                <span itemprop="about" itemscope itemtype="http://schema.org/Thing">
                  <a href="/categories/%E9%87%8F%E5%8C%96%E6%8A%95%E8%B5%84/" itemprop="url" rel="index">
                    <span itemprop="name">量化投资</span>
                  </a>
                </span>

                
                
              
            </span>
          

          
            
          

          
          

          

          
            <div class="post-wordcount">
              
                
                  <span class="post-meta-divider">|</span>
                
                <span class="post-meta-item-icon">
                  <i class="fa fa-file-word-o"></i>
                </span>
                
                  <span class="post-meta-item-text">字数统计&#58;</span>
                
                <span title="字数统计">
                  2.2k
                </span>
              

              
                <span class="post-meta-divider">|</span>
              

              
                <span class="post-meta-item-icon">
                  <i class="fa fa-clock-o"></i>
                </span>
                
                  <span class="post-meta-item-text">阅读时长 &asymp;</span>
                
                <span title="阅读时长">
                  10
                </span>
              
            </div>
          

          

        </div>
      </header>
    

    
    
    
    <div class="post-body" itemprop="articleBody">

      
      

      
        <p>下面对上次实现的多因子选股模型进行一些改进。<br>首先来看评分标准，增加几个系数。</p>
<figure class="highlight python"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br></pre></td><td class="code"><pre><span class="line"><span class="comment"># 计算评分指标</span></span><br><span class="line"><span class="function"><span class="keyword">def</span> <span class="title">scale</span>(<span class="params">factors, a1=<span class="number">1.0</span>, a2 = <span class="number">1.0</span>, a3 = <span class="number">1.0</span>, a4 = <span class="number">1.0</span>, a5 = <span class="number">1.0</span></span>):</span></span><br><span class="line">    pe = -<span class="number">1.0</span>*a1*factors.pe/factors.pe.mean()</span><br><span class="line">    esp = a2*factors.esp/factors.esp.mean()</span><br><span class="line">    bvps = a3*factors.bvps/factors.bvps.mean()</span><br><span class="line">    pb = a4*factors.pb/factors.pb.mean()</span><br><span class="line">    npr = a5*factors.npr/factors.npr.mean()</span><br><span class="line">    score = pe+esp+bvps+pb+npr</span><br><span class="line">    <span class="comment"># print(score)</span></span><br><span class="line">    <span class="comment"># 排序并画图</span></span><br><span class="line">    score = score.sort_values()</span><br><span class="line">    <span class="comment"># print(score)</span></span><br><span class="line">    <span class="comment"># score.plot(kind = &quot;hist&quot;, bins = 1000, range = (-25.0, 30.0))</span></span><br><span class="line">    <span class="comment"># plt.savefig(&quot;fsctorScore.png&quot;)</span></span><br><span class="line">    <span class="keyword">return</span> score</span><br></pre></td></tr></table></figure>
<p>也就是为每个因子赋予不同的权重，然后找到最佳的因子权重组合。<br>专门写一个函数。</p>
<figure class="highlight python"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br><span class="line">22</span><br><span class="line">23</span><br><span class="line">24</span><br><span class="line">25</span><br><span class="line">26</span><br><span class="line">27</span><br><span class="line">28</span><br><span class="line">29</span><br><span class="line">30</span><br><span class="line">31</span><br><span class="line">32</span><br></pre></td><td class="code"><pre><span class="line"><span class="comment"># 对不同的因子权重组合进行优化</span></span><br><span class="line"><span class="function"><span class="keyword">def</span> <span class="title">optStrategy</span>(<span class="params">factors, strategy, cash = <span class="number">1000000</span>, bDraw = <span class="literal">False</span></span>):</span></span><br><span class="line">    start = <span class="string">&quot;2018-01-01&quot;</span></span><br><span class="line">    end = <span class="string">&quot;2020-07-05&quot;</span></span><br><span class="line"></span><br><span class="line">    res = []</span><br><span class="line">    maxRes = <span class="number">0.0</span></span><br><span class="line">    maxParams = [<span class="number">0</span>, <span class="number">0</span>, <span class="number">0</span>, <span class="number">0</span>, <span class="number">0</span>]</span><br><span class="line">    x = <span class="number">200</span></span><br><span class="line">    step = <span class="number">100</span></span><br><span class="line">    <span class="keyword">for</span> a1 <span class="keyword">in</span> <span class="built_in">range</span>(<span class="number">1</span>, x, step):</span><br><span class="line">        <span class="keyword">for</span> a2 <span class="keyword">in</span> <span class="built_in">range</span>(<span class="number">1</span>, x, step):</span><br><span class="line">            <span class="keyword">for</span> a3 <span class="keyword">in</span> <span class="built_in">range</span>(<span class="number">1</span>, x, step):</span><br><span class="line">                <span class="keyword">for</span> a4 <span class="keyword">in</span> <span class="built_in">range</span>(<span class="number">1</span>, x, step):</span><br><span class="line">                    <span class="keyword">for</span> a5 <span class="keyword">in</span> <span class="built_in">range</span>(<span class="number">1</span>, x, step):</span><br><span class="line">                        score = scale(factors, a1, a2, a3, a4, a5)</span><br><span class="line">                        codes = score[-<span class="number">10</span>:].index</span><br><span class="line">                        <span class="comment"># 准备数据</span></span><br><span class="line">                        name = factors.loc[codes, <span class="string">&quot;name&quot;</span>].values</span><br><span class="line">                        <span class="comment"># 将汉字转换为拼音</span></span><br><span class="line">                        p = Pinyin()</span><br><span class="line">                        name = [p.get_pinyin(s) <span class="keyword">for</span> s <span class="keyword">in</span> name]</span><br><span class="line">                        code = [<span class="built_in">str</span>(x) <span class="keyword">for</span> x <span class="keyword">in</span> codes]</span><br><span class="line">                        opttest = backtest.BackTest(strategy, start, end, code, name, cash)</span><br><span class="line">                        result = opttest.run()</span><br><span class="line">                        print(<span class="string">&quot;a1 = &#123;&#125;, a2 = &#123;&#125;, a3 = &#123;&#125;, a4 = &#123;&#125;, a5 = &#123;&#125;, 年化收益率: &#123;&#125;\n&quot;</span>.<span class="built_in">format</span>(a1, a2, a3, a4, a5, result.年化收益率))</span><br><span class="line">                        res.append(result.年化收益率)</span><br><span class="line">                        <span class="keyword">if</span> result.年化收益率 &gt; maxRes:</span><br><span class="line">                            maxRes = result.年化收益率</span><br><span class="line">                            maxParams = [a1, a2, a3, a4, a5]</span><br><span class="line">    print(<span class="string">&quot;最佳权重:&quot;</span>, maxParams, <span class="string">&quot;最大年化收益率:&quot;</span>, maxRes)</span><br><span class="line">    <span class="keyword">return</span> res</span><br></pre></td></tr></table></figure>
<p>用的最简单的穷举法。<br><img src="https://zymblog-1258069789.cos.ap-chengdu.myqcloud.com/blog0178-QTLearn/59/01.png"><br>尝试的情况太大时，手机跑了一个多小时，最后termux死了。只能用最少的情况来测试。看来还是得搞个服务器。<br><img src="https://zymblog-1258069789.cos.ap-chengdu.myqcloud.com/blog0178-QTLearn/59/02.png"><br>尝试用比穷举好的算法，先试一下随机算法，即在解空间内随机生成系数，再比较年化收益率。<br>代码如下:</p>
<figure class="highlight python"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br><span class="line">22</span><br><span class="line">23</span><br><span class="line">24</span><br><span class="line">25</span><br><span class="line">26</span><br><span class="line">27</span><br><span class="line">28</span><br><span class="line">29</span><br><span class="line">30</span><br><span class="line">31</span><br><span class="line">32</span><br></pre></td><td class="code"><pre><span class="line"><span class="comment"># 采用随机算法进行优化</span></span><br><span class="line"><span class="function"><span class="keyword">def</span> <span class="title">randOpt</span>(<span class="params">factors, strategy, times = <span class="number">100</span>, cash = <span class="number">1000000</span>, bDraw = <span class="literal">False</span></span>):</span></span><br><span class="line">    start = <span class="string">&quot;2018-01-01&quot;</span></span><br><span class="line">    end = <span class="string">&quot;2020-07-05&quot;</span></span><br><span class="line"></span><br><span class="line">    res = []</span><br><span class="line">    maxRes = <span class="number">0.0</span></span><br><span class="line">    maxParams = [<span class="number">0</span>, <span class="number">0</span>, <span class="number">0</span>, <span class="number">0</span>, <span class="number">0</span>]</span><br><span class="line">    random.seed()</span><br><span class="line">    <span class="keyword">for</span> i <span class="keyword">in</span> <span class="built_in">range</span>(times):</span><br><span class="line">        a1 = random.randint(<span class="number">1</span>, <span class="number">200</span>)</span><br><span class="line">        a2 = random.randint(<span class="number">1</span>, <span class="number">200</span>)</span><br><span class="line">        a3 = random.randint(<span class="number">1</span>, <span class="number">200</span>)</span><br><span class="line">        a4 = random.randint(<span class="number">1</span>, <span class="number">200</span>)</span><br><span class="line">        a5 = random.randint(<span class="number">1</span>, <span class="number">200</span>)</span><br><span class="line">        score = scale(factors, a1, a2, a3, a4, a5)</span><br><span class="line">        codes = score[-<span class="number">10</span>:].index</span><br><span class="line">        <span class="comment"># 准备数据</span></span><br><span class="line">        name = factors.loc[codes, <span class="string">&quot;name&quot;</span>].values</span><br><span class="line">        <span class="comment"># 将汉字转换为拼音</span></span><br><span class="line">        p = Pinyin()</span><br><span class="line">        name = [p.get_pinyin(s) <span class="keyword">for</span> s <span class="keyword">in</span> name]</span><br><span class="line">        code = [<span class="built_in">str</span>(x) <span class="keyword">for</span> x <span class="keyword">in</span> codes]</span><br><span class="line">        opttest = backtest.BackTest(strategy, start, end, code, name, cash)</span><br><span class="line">        result = opttest.run()</span><br><span class="line">        print(<span class="string">&quot;第&#123;&#125;次尝试:a1 = &#123;&#125;, a2 = &#123;&#125;, a3 = &#123;&#125;, a4 = &#123;&#125;, a5 = &#123;&#125;, 年化收益率: &#123;&#125;\n&quot;</span>.<span class="built_in">format</span>(i+<span class="number">1</span>, a1, a2, a3, a4, a5, result.年化收益率))</span><br><span class="line">        res.append(result.年化收益率)</span><br><span class="line">        <span class="keyword">if</span> result.年化收益率 &gt; maxRes:</span><br><span class="line">            maxRes = result.年化收益率</span><br><span class="line">            maxParams = [a1, a2, a3, a4, a5]</span><br><span class="line">    print(<span class="string">&quot;最佳权重:&quot;</span>, maxParams, <span class="string">&quot;最大年化收益率:&quot;</span>, maxRes)</span><br><span class="line">    <span class="keyword">return</span> res</span><br></pre></td></tr></table></figure>
<p>解的空间为[1,200)，穷举的话，约200^5次尝试。结果为:<br><img src="https://zymblog-1258069789.cos.ap-chengdu.myqcloud.com/blog0178-QTLearn/59/03.png"><br>看来最重要的指标是市净率。<br><img src="https://zymblog-1258069789.cos.ap-chengdu.myqcloud.com/blog0178-QTLearn/59/04.png"><br>现在的问题是有没有办法能扩大搜索范围而效率又更高?<br>先试试多元线性回归吧。为了获取数据，再把上面的随机算法运行一次，记录每次的5个参数，以及相应的回测年化收益率。<br>运行完结果是这样<br><img src="https://zymblog-1258069789.cos.ap-chengdu.myqcloud.com/blog0178-QTLearn/59/05.png"><br>画图看看<br><img src="https://zymblog-1258069789.cos.ap-chengdu.myqcloud.com/blog0178-QTLearn/59/06.png"><br>看图，市盈率的权重与年化收益率无明显相关关系，每股收益，每股净资产，每股利润的权重与年化收益率都是呈负相关，而市净率的权重与年化收率是呈正相关。但在年化收益率0.1-0.2之间有个区域，权重的改变对其无影响。要不要考虑把这些数据给剔除掉？<br><img src="https://zymblog-1258069789.cos.ap-chengdu.myqcloud.com/blog0178-QTLearn/59/07.png"></p>
<p>剔除以后的情况，先用多元线性回归试试。<br>之前在手机的termux里运行包含sklearn库的程序时，总是提示：<br>“This platform lacks a functioning sem_open implementation, therefore, the required synchronization primitives needed will not function, see issue 3770.”<br>没有找到解决方法，只能传到服务器或者docker里运行。刚又搜了一下，找到一个解决方案：把sklearn版本退回到0.19.2，<br>如下：</p>
<figure class="highlight python"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line">pip install scikit-learn==<span class="number">0.19</span><span class="number">.2</span></span><br></pre></td></tr></table></figure>
<p>搞定！现在程序在termux里运行正常了。只是只能单线程执行。<br>参考了 <a target="_blank" rel="noopener" href="https://www.jianshu.com/p/dc53be46d172">https://www.jianshu.com/p/dc53be46d172</a> 特此感谢！</p>
<figure class="highlight python"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br><span class="line">22</span><br><span class="line">23</span><br><span class="line">24</span><br><span class="line">25</span><br><span class="line">26</span><br><span class="line">27</span><br><span class="line">28</span><br><span class="line">29</span><br><span class="line">30</span><br><span class="line">31</span><br><span class="line">32</span><br><span class="line">33</span><br></pre></td><td class="code"><pre><span class="line"><span class="comment"># 回归分析</span></span><br><span class="line"><span class="function"><span class="keyword">def</span> <span class="title">regress</span>(<span class="params">data</span>):</span></span><br><span class="line">    print(data)</span><br><span class="line">    draw(data, <span class="string">&quot;factor_analysis.png&quot;</span>)</span><br><span class="line">    <span class="comment"># 剔除年化收益率在0.1-0.2之间的数据</span></span><br><span class="line">    data = data[(data.result &lt; <span class="number">0.1</span>) | (data.result &gt; <span class="number">0.2</span>)]</span><br><span class="line">    draw(data, <span class="string">&quot;factor_after_clean.png&quot;</span>)</span><br><span class="line">    <span class="comment"># 进行多元线性回归</span></span><br><span class="line">    <span class="comment"># 划分数据</span></span><br><span class="line">    print(data.describe())</span><br><span class="line">    X = data.loc[:, [<span class="string">&quot;a1&quot;</span>, <span class="string">&quot;a2&quot;</span>, <span class="string">&quot;a3&quot;</span>, <span class="string">&quot;a4&quot;</span>, <span class="string">&quot;a5&quot;</span>]]</span><br><span class="line">    Y = data.loc[:, [<span class="string">&quot;result&quot;</span>]]</span><br><span class="line"><span class="comment">#    print(X.count())</span></span><br><span class="line"><span class="comment">#    n = len(X)</span></span><br><span class="line"><span class="comment">#    X_train = X.iloc[:int(n*0.75), :].reset_index(drop = True)</span></span><br><span class="line"><span class="comment">#    X_test = X.iloc[int(n*0.75):, :].reset_index(drop = True)</span></span><br><span class="line"><span class="comment">#    Y_train = Y.iloc[:int(n*0.75), :].reset_index(drop = True)</span></span><br><span class="line"><span class="comment">#    Y_test = Y.iloc[int(n*0.75):, :].reset_index(drop = True)</span></span><br><span class="line"><span class="comment">#    print(X_train.count(), Y_test)</span></span><br><span class="line">    X_train, X_test, Y_train, Y_test = train_test_split(X, Y, test_size = <span class="number">0.25</span>, random_state = <span class="number">1</span>)</span><br><span class="line">    print(X_test, Y_test)</span><br><span class="line">    <span class="comment"># 建模</span></span><br><span class="line">    model = LinearRegression()</span><br><span class="line">    model.fit(X_train, Y_train)</span><br><span class="line">    predictions = model.predict(X_test)</span><br><span class="line">    <span class="keyword">for</span> i, prediction <span class="keyword">in</span> <span class="built_in">enumerate</span>(predictions):</span><br><span class="line">        print(i)</span><br><span class="line">        print(<span class="string">&quot;预测值:%s, 目标值:%s&quot;</span> % (prediction, Y_test.iloc[i, :]))</span><br><span class="line">    print(<span class="string">&quot;R平方值:%.2f&quot;</span> % model.score(X_test, Y_test))</span><br><span class="line">    MSE = metrics.mean_squared_error(Y_test, predictions)</span><br><span class="line">    RMSE = np.sqrt(MSE)</span><br><span class="line">    print(<span class="string">&quot;MSE:&quot;</span>, MSE)</span><br><span class="line">    print(<span class="string">&quot;RMSE:&quot;</span>, RMSE)</span><br></pre></td></tr></table></figure>
<p><img src="https://zymblog-1258069789.cos.ap-chengdu.myqcloud.com/blog0178-QTLearn/59/08.png"><br>结果很差，画图看看。<br><img src="https://zymblog-1258069789.cos.ap-chengdu.myqcloud.com/blog0178-QTLearn/59/09.png"><br>看图倒还不错。<br>画散点图看看。<br><img src="https://zymblog-1258069789.cos.ap-chengdu.myqcloud.com/blog0178-QTLearn/59/10.png"><br>看来还要生成更大的数据集来训练。<br>用回归的模型选择系数权重再回测一下看看。</p>
<figure class="highlight python"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br><span class="line">22</span><br><span class="line">23</span><br><span class="line">24</span><br><span class="line">25</span><br><span class="line">26</span><br><span class="line">27</span><br><span class="line">28</span><br><span class="line">29</span><br><span class="line">30</span><br><span class="line">31</span><br><span class="line">32</span><br><span class="line">33</span><br><span class="line">34</span><br></pre></td><td class="code"><pre><span class="line"><span class="comment"># 用线性回归所得模型选择因子权重</span></span><br><span class="line"><span class="function"><span class="keyword">def</span> <span class="title">regressChoose</span>(<span class="params">factors, strategy, model, times = <span class="number">200</span>, cash = <span class="number">1000000</span>, bDraw = <span class="literal">False</span></span>):</span></span><br><span class="line">    start = <span class="string">&quot;2018-01-01&quot;</span></span><br><span class="line">    end = <span class="string">&quot;2020-07-05&quot;</span></span><br><span class="line"></span><br><span class="line">    random.seed()</span><br><span class="line">    best  = <span class="number">0.0</span></span><br><span class="line">    bestWeight = [<span class="number">0</span>, <span class="number">0</span>, <span class="number">0</span>, <span class="number">0</span>, <span class="number">0</span>]</span><br><span class="line">    data = pd.DataFrame()</span><br><span class="line">    <span class="keyword">for</span> i <span class="keyword">in</span> <span class="built_in">range</span>(times):</span><br><span class="line">        a1 = random.randint(<span class="number">1</span>, <span class="number">200</span>)</span><br><span class="line">        a2 = random.randint(<span class="number">1</span>, <span class="number">200</span>)</span><br><span class="line">        a3 = random.randint(<span class="number">1</span>, <span class="number">200</span>)</span><br><span class="line">        a4 = random.randint(<span class="number">1</span>, <span class="number">200</span>)</span><br><span class="line">        a5 = random.randint(<span class="number">1</span>, <span class="number">200</span>)</span><br><span class="line">        data = data.append(pd.DataFrame(&#123;<span class="string">&quot;a1&quot;</span>:[a1], <span class="string">&quot;a2&quot;</span>:[a2], <span class="string">&quot;a3&quot;</span>:[a3], <span class="string">&quot;a4&quot;</span>:[a4], <span class="string">&quot;a5&quot;</span>:[a5]&#125;), ignore_index = <span class="literal">True</span>)</span><br><span class="line">    <span class="comment"># print(data)</span></span><br><span class="line">    pred = model.predict(data)</span><br><span class="line">    print(<span class="built_in">type</span>(pred), pred.<span class="built_in">max</span>(), np.argmax(pred))</span><br><span class="line">    best = pred.<span class="built_in">max</span>()</span><br><span class="line">    bestPos = np.argmax(pred)</span><br><span class="line">    bestWeight = [data.iloc[bestPos, <span class="number">0</span>], data.iloc[bestPos, <span class="number">1</span>], data.iloc[bestPos, <span class="number">2</span>], data.iloc[bestPos, <span class="number">3</span>], data.iloc[bestPos, <span class="number">4</span>]]</span><br><span class="line">    score = scale(factors, bestWeight[<span class="number">0</span>], bestWeight[<span class="number">1</span>], bestWeight[<span class="number">2</span>], bestWeight[<span class="number">3</span>], bestWeight[<span class="number">4</span>])</span><br><span class="line">    codes = score[-<span class="number">10</span>:].index</span><br><span class="line">    <span class="comment"># 准备数据</span></span><br><span class="line">    name = factors.loc[codes, <span class="string">&quot;name&quot;</span>].values</span><br><span class="line">    <span class="comment"># 将汉字转换为拼音</span></span><br><span class="line">    p = Pinyin()</span><br><span class="line">    name = [p.get_pinyin(s) <span class="keyword">for</span> s <span class="keyword">in</span> name]</span><br><span class="line">    code = [<span class="built_in">str</span>(x) <span class="keyword">for</span> x <span class="keyword">in</span> codes]</span><br><span class="line">    opttest = backtest.BackTest(strategy, start, end, code, name, cash)</span><br><span class="line">    result = opttest.run()</span><br><span class="line">    print(<span class="string">&quot;模型预测年化收益率&#123;&#125;, 实际回测年化收益率: &#123;&#125;\n&quot;</span>.<span class="built_in">format</span>(best, result.年化收益率))</span><br><span class="line">    <span class="keyword">return</span> bestWeight  </span><br></pre></td></tr></table></figure>
<p>结果<br><img src="https://zymblog-1258069789.cos.ap-chengdu.myqcloud.com/blog0178-QTLearn/59/11.png"><br>差别很小的，跟一开始的随机算法相比，这么做优点是不用每组值都进行回测，那个很耗时间的。这样可以增加尝试次数。试试增加到10000次吧。<br><img src="https://zymblog-1258069789.cos.ap-chengdu.myqcloud.com/blog0178-QTLearn/59/12.png"><br>用了大概10秒钟。<br>还有个问题，就是是不是每次运行都需要训练模型，能不能保存下来，下次直接用？<br>用sklearn的joblib即可。</p>
<figure class="highlight python"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br></pre></td><td class="code"><pre><span class="line"><span class="comment"># 保存模型</span></span><br><span class="line">joblib.dump(model, <span class="string">&quot;Regress.m&quot;</span>)</span><br><span class="line"><span class="comment"># 加载模型</span></span><br><span class="line">model = joblib.load(<span class="string">&quot;Regress.m&quot;</span>)</span><br></pre></td></tr></table></figure>
<p>现在就可以把回归模型那里注释掉啦。另外再扩大因子权重的取值范围，到1000看看。<br><img src="https://zymblog-1258069789.cos.ap-chengdu.myqcloud.com/blog0178-QTLearn/59/13.png"></p>
<p>现在差距就比较大了，而且实测下来的年化收益率并没有增加多少，因此还是改回原来的200以内的范围。程序有好多重复的地方，重构一下。然后再运行随机算法，模拟次数多一点，多生成一些数据。<br>在我的手机上试了两次，基本上模拟超过200次就比较悬了，不知道什么时候就死了。传到诊室电脑上试试。<br>在电脑上大概每秒钟能回测一次，我用随机权重系数回测了4000次，生成4000组数据。再把数据传回手机进行回归和选股。<br><img src="https://zymblog-1258069789.cos.ap-chengdu.myqcloud.com/blog0178-QTLearn/59/14.png"><br>数据多了果然好点。<br>接下来，就用筛选出来的股票池再进行回测，换一个时间范围看看。</p>
<figure class="highlight python"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br></pre></td><td class="code"><pre><span class="line"><span class="comment"># 根据输入的股票池进行回测检验</span></span><br><span class="line"><span class="function"><span class="keyword">def</span> <span class="title">checkResult</span>(<span class="params">strategy, codes, names, start, end, cash = <span class="number">1000000</span></span>):</span></span><br><span class="line">    opttest = backtest.BackTest(strategy, start, end, codes, names, cash)</span><br><span class="line">    result = opttest.run()</span><br><span class="line">    print(<span class="string">&quot;回测结果&quot;</span>)</span><br><span class="line">    print(result)</span><br></pre></td></tr></table></figure>
<p>回测10年的数据。<br><img src="https://zymblog-1258069789.cos.ap-chengdu.myqcloud.com/blog0178-QTLearn/59/15.png"><br>回测十年，结果蛮不错的。<br>接下来，如果是正儿八经的量化策略研究，就该上实盘了吧?<br>嘿嘿，再研究下有没有其它方法吧。我在知乎上提问了:<a target="_blank" rel="noopener" href="https://www.zhihu.com/question/417584064">https://www.zhihu.com/question/417584064</a><br>没人回我……</p>
<p>下次了。<br>代码地址还是： <a target="_blank" rel="noopener" href="https://github.com/zwdnet/MyQuant/tree/master/47">https://github.com/zwdnet/MyQuant/tree/master/47</a><br>策略文件为facts.py。</p>
<p>我发文章的三个地方，欢迎大家在朋友圈等地方分享，欢迎点“在看”。<br>我的个人博客地址：<a href="https://zwdnet.github.io/">https://zwdnet.github.io</a><br>我的知乎文章地址： <a target="_blank" rel="noopener" href="https://www.zhihu.com/people/zhao-you-min/posts">https://www.zhihu.com/people/zhao-you-min/posts</a><br>我的微信个人订阅号：赵瑜敏的口腔医学学习园地</p>
<p><img src="https://zymblog-1258069789.cos.ap-chengdu.myqcloud.com/other/wx.jpg"></p>

      
    </div>
    
    
    

    

    
      <div>
        <div style="padding: 10px 0; margin: 20px auto; width: 90%; text-align: center;">
  <div>欢迎打赏！感谢支持！</div>
  <button id="rewardButton" disable="enable" onclick="var qr = document.getElementById('QR'); if (qr.style.display === 'none') {qr.style.display='block';} else {qr.style.display='none'}">
    <span>打赏</span>
  </button>
  <div id="QR" style="display: none;">

    
      <div id="wechat" style="display: inline-block">
        <img id="wechat_qr" src="https://zymblog-1258069789.cos.ap-chengdu.myqcloud.com/other/mm_facetoface_collect_qrcode_1542944836634.png" alt=" 微信支付"/>
        <p>微信支付</p>
      </div>
    

    
      <div id="alipay" style="display: inline-block">
        <img id="alipay_qr" src="https://zymblog-1258069789.cos.ap-chengdu.myqcloud.com/other/1542944857770.jpg" alt=" 支付宝"/>
        <p>支付宝</p>
      </div>
    

    

  </div>
</div>

      </div>
    

    

    <footer class="post-footer">
      
        <div class="post-tags">
          
            <a href="/tags/%E5%AD%A6%E4%B9%A0%E7%AC%94%E8%AE%B0/" rel="tag"># 学习笔记</a>
          
            <a href="/tags/%E9%87%8F%E5%8C%96%E6%8A%95%E8%B5%84/" rel="tag"># 量化投资</a>
          
            <a href="/tags/%E7%BA%BF%E6%80%A7%E5%9B%9E%E5%BD%92/" rel="tag"># 线性回归</a>
          
            <a href="/tags/Backtrader/" rel="tag"># Backtrader</a>
          
            <a href="/tags/%E5%A4%9A%E5%9B%A0%E5%AD%90%E9%80%89%E8%82%A1/" rel="tag"># 多因子选股</a>
          
        </div>
      

      
      
      

      
        <div class="post-nav">
          <div class="post-nav-next post-nav-item">
            
              <a href="/2020/08/24/%E9%87%8F%E5%8C%96%E6%8A%95%E8%B5%84%E5%AD%A6%E4%B9%A0%E7%AC%94%E8%AE%B085%E2%80%94%E2%80%94%E5%AE%9E%E7%8E%B0%E9%87%8F%E5%8C%96%E4%BA%A4%E6%98%93%E7%BB%8F%E5%85%B8%E7%AD%96%E7%95%A5-%E5%A4%9A%E5%9B%A0%E5%AD%90%E9%80%89%E8%82%A1/" rel="next" title="量化投资学习笔记85——实现量化交易经典策略:多因子选股">
                <i class="fa fa-chevron-left"></i> 量化投资学习笔记85——实现量化交易经典策略:多因子选股
              </a>
            
          </div>

          <span class="post-nav-divider"></span>

          <div class="post-nav-prev post-nav-item">
            
              <a href="/2020/08/30/%E6%A0%91%E8%84%82%E7%B2%98%E6%8E%A5%E5%BC%8F%E5%9B%BA%E5%AE%9A%E6%A1%A5%E7%9A%84%E6%9C%AF%E5%89%8D%E5%87%86%E5%A4%87%E5%92%8C%E4%B8%B4%E5%BA%8A%E6%B5%81%E7%A8%8B%E2%80%94%E2%80%94%E9%94%90%E8%AF%BB%E4%BC%9A%E8%AF%BE%E7%A8%8B%E7%AC%94%E8%AE%B002/" rel="prev" title="树脂粘接式固定桥的术前准备和临床流程——锐读会课程笔记02">
                树脂粘接式固定桥的术前准备和临床流程——锐读会课程笔记02 <i class="fa fa-chevron-right"></i>
              </a>
            
          </div>
        </div>
      

      
      
    </footer>
  </div>
  
  
  
  </article>



    <div class="post-spread">
      
    </div>
  </div>


          </div>
          


          

  
    <div class="comments" id="comments">
      <div id="lv-container" data-id="city" data-uid="MTAyMC80MTA2Mi8xNzU4Nw=="></div>
    </div>

  



        </div>
        
          
  
  <div class="sidebar-toggle">
    <div class="sidebar-toggle-line-wrap">
      <span class="sidebar-toggle-line sidebar-toggle-line-first"></span>
      <span class="sidebar-toggle-line sidebar-toggle-line-middle"></span>
      <span class="sidebar-toggle-line sidebar-toggle-line-last"></span>
    </div>
  </div>

  <aside id="sidebar" class="sidebar">
    
    <div class="sidebar-inner">

      

      

      <section class="site-overview-wrap sidebar-panel sidebar-panel-active">
        <div class="site-overview">
          <div class="site-author motion-element" itemprop="author" itemscope itemtype="http://schema.org/Person">
            
              <img class="site-author-image" itemprop="image"
                src="https://zymblog-1258069789.cos.ap-chengdu.myqcloud.com/other/tx.jpg"
                alt="" />
            
              <p class="site-author-name" itemprop="name"></p>
              <p class="site-description motion-element" itemprop="description"></p>
          </div>

          <nav class="site-state motion-element">

            
              <div class="site-state-item site-state-posts">
              
                <a href="/archives/%20%7C%7C%20archive">
              
                  <span class="site-state-item-count">452</span>
                  <span class="site-state-item-name">日志</span>
                </a>
              </div>
            

            
              
              
              <div class="site-state-item site-state-categories">
                <a href="/categories/index.html">
                  <span class="site-state-item-count">29</span>
                  <span class="site-state-item-name">分类</span>
                </a>
              </div>
            

            
              
              
              <div class="site-state-item site-state-tags">
                <a href="/tags/index.html">
                  <span class="site-state-item-count">544</span>
                  <span class="site-state-item-name">标签</span>
                </a>
              </div>
            

          </nav>

          

          

          
          

          
          

          

        </div>
      </section>

      

      

    </div>
  </aside>


        
      </div>
    </main>

    <footer id="footer" class="footer">
      <div class="footer-inner">
        <div class="copyright">&copy; <span itemprop="copyrightYear">2021</span>
  <span class="with-love">
    <i class="fa fa-user"></i>
  </span>
  <span class="author" itemprop="copyrightHolder">本站版权归赵瑜敏所有，如欲转载请与本人联系。</span>

  
    <span class="post-meta-divider">|</span>
    <span class="post-meta-item-icon">
      <i class="fa fa-area-chart"></i>
    </span>
    
      <span class="post-meta-item-text">Site words total count&#58;</span>
    
    <span title="Site words total count">1225.8k</span>
  
</div>









<div>
  <script type="text/javascript">var cnzz_protocol = (("https:" == document.location.protocol) ? " https://" : " http://");document.write(unescape("%3Cspan id='cnzz_stat_icon_1275447216'%3E%3C/span%3E%3Cscript src='" + cnzz_protocol + "s11.cnzz.com/z_stat.php%3Fid%3D1275447216%26online%3D1%26show%3Dline' type='text/javascript'%3E%3C/script%3E"));</script>
</div>

        







  <div style="display: none;">
    <script src="//s95.cnzz.com/z_stat.php?id=1275447216&web_id=1275447216" language="JavaScript"></script>
  </div>



        
      </div>
    </footer>

    
      <div class="back-to-top">
        <i class="fa fa-arrow-up"></i>
        
      </div>
    

    

  </div>

  

<script type="text/javascript">
  if (Object.prototype.toString.call(window.Promise) !== '[object Function]') {
    window.Promise = null;
  }
</script>









  












  
  
    <script type="text/javascript" src="/lib/jquery/index.js?v=2.1.3"></script>
  

  
  
    <script type="text/javascript" src="/lib/fastclick/lib/fastclick.min.js?v=1.0.6"></script>
  

  
  
    <script type="text/javascript" src="/lib/jquery_lazyload/jquery.lazyload.js?v=1.9.7"></script>
  

  
  
    <script type="text/javascript" src="/lib/velocity/velocity.min.js?v=1.2.1"></script>
  

  
  
    <script type="text/javascript" src="/lib/velocity/velocity.ui.min.js?v=1.2.1"></script>
  

  
  
    <script type="text/javascript" src="/lib/fancybox/source/jquery.fancybox.pack.js?v=2.1.5"></script>
  


  


  <script type="text/javascript" src="/js/src/utils.js?v=5.1.4"></script>

  <script type="text/javascript" src="/js/src/motion.js?v=5.1.4"></script>



  
  


  <script type="text/javascript" src="/js/src/affix.js?v=5.1.4"></script>

  <script type="text/javascript" src="/js/src/schemes/pisces.js?v=5.1.4"></script>



  
  <script type="text/javascript" src="/js/src/scrollspy.js?v=5.1.4"></script>
<script type="text/javascript" src="/js/src/post-details.js?v=5.1.4"></script>



  


  <script type="text/javascript" src="/js/src/bootstrap.js?v=5.1.4"></script>



  


  




	





  





  
    <script type="text/javascript">
      (function(d, s) {
        var j, e = d.getElementsByTagName(s)[0];
        if (typeof LivereTower === 'function') { return; }
        j = d.createElement(s);
        j.src = 'https://cdn-city.livere.com/js/embed.dist.js';
        j.async = true;
        e.parentNode.insertBefore(j, e);
      })(document, 'script');
    </script>
  












  





  

  

  

  
  

  

  

  

  
</body>
</html>
